home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / pp / pp-6.0 / Src / qmgr / ryresponder.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-12-18  |  11.8 KB  |  600 lines

  1. /* ryresponder.c - responder stuff - mackled out of ryresponder.c */
  2.  
  3. # ifndef lint
  4. static char Rcsid[] = "@(#)$Header: /xtel/pp/pp-beta/Src/qmgr/RCS/ryresponder.c,v 6.0 1991/12/18 20:27:38 jpo Rel $";
  5. # endif
  6.  
  7. /*
  8.  * $Header: /xtel/pp/pp-beta/Src/qmgr/RCS/ryresponder.c,v 6.0 1991/12/18 20:27:38 jpo Rel $
  9.  *
  10.  * $Log: ryresponder.c,v $
  11.  * Revision 6.0  1991/12/18  20:27:38  jpo
  12.  * Release 6.0
  13.  *
  14.  */
  15.  
  16.  
  17.  
  18. #include "util.h"
  19. #include "qmgr.h"
  20. #include "ryresponder.h"
  21. #include <isode/tsap.h>         /* for listening */
  22. #include <varargs.h>
  23. #include <fcntl.h>
  24. #include <signal.h>
  25.  
  26. /*     DATA */
  27.  
  28. char     *myname = "qmgr";
  29. static jmp_buf  toplevel;
  30. static IFP      startfnx;
  31. static IFP      stopfnx;
  32. static int      ros_init (),
  33.         ros_work (),
  34.         ros_lose ();
  35. static void    ros_indication ();
  36. extern void    chan_manage (),
  37.         isodeexport (),
  38.         init_chans ();
  39. extern int      errno;
  40. extern int    nobackground;
  41. extern time_t    time ();
  42. fd_set          perf_rfds,
  43.         perf_wfds;
  44. int             perf_nfds;
  45. int        delaytime = NOTOK;
  46. extern time_t current_time;
  47.  
  48. void        start_specials (), schedule ();
  49.  
  50. static int  TMagic (vecp, vec, td)
  51. int     *vecp;
  52. char   **vec;
  53. struct TSAPdisconnect *td;
  54. {
  55.     int     sd;
  56.     struct TSAPstart tss;
  57.     register struct TSAPstart  *ts = &tss;
  58.  
  59.     if (TInit (*vecp, vec, ts, td) == NOTOK)
  60.         return NOTOK;
  61.     sd = ts -> ts_sd;
  62.  
  63.     if (TConnResponse (sd, &ts -> ts_called, ts -> ts_expedited, NULLCP, 0,
  64.                NULLQOS, td) == NOTOK)
  65.         return NOTOK;
  66.  
  67.     if (TSaveState (sd, vec + 1, td) == NOTOK)
  68.         return NOTOK;
  69.     vec[*vecp = 2] = NULL;
  70.  
  71.     return OK;
  72. }
  73.  
  74. background ()
  75. {
  76.     int i;
  77.  
  78.     for (i = 0; i < 5; i++) {
  79.         switch (fork ()) {
  80.             case NOTOK: 
  81.             sleep (5);
  82.             continue;
  83.  
  84.             case OK: 
  85.             break;
  86.  
  87.             default: 
  88.             _exit (0);
  89.         }
  90.         break;
  91.     }
  92.  
  93.     if ((i = open ("/dev/null", O_RDWR)) != NOTOK) {
  94.         if (i != 0)
  95.             (void) dup2 (i, 0), (void) close (i);
  96.         (void) dup2 (0, 1);
  97.         (void) dup2 (0, 2);
  98.     }
  99.  
  100. #ifdef    SETSID
  101.     (void) setsid ();
  102. #endif
  103. #ifdef    TIOCNOTTY
  104.     if ((i = open ("/dev/tty", O_RDWR)) != NOTOK) {
  105.         (void) ioctl (i, TIOCNOTTY, NULLCP);
  106.         (void) close (i);
  107.     }
  108. #else
  109. #ifdef    SYS5
  110.     (void) setpgrp ();
  111.     (void) signal (SIGINT, SIG_IGN);
  112.     (void) signal (SIGQUIT, SIG_IGN);
  113. #endif
  114. #endif
  115.     isodexport (NULLCP);    /* re-initialize logfiles */
  116. }
  117.  
  118. /*     RESPONDER */
  119.  
  120. int     ryresponder (argc, argv, host, myservice, dispatches, ops, start, stop)
  121. int     argc;
  122. char  **argv,
  123.        *host,
  124.        *myservice;
  125. struct server_dispatch *dispatches;
  126. struct RyOperation *ops;
  127. IFP     start,
  128.     stop;
  129. {
  130.     register struct server_dispatch   *ds;
  131.     AEI     aei;
  132.     struct TSAPdisconnect   tds;
  133.     struct TSAPdisconnect  *td = &tds;
  134.     struct RoSAPindication  rois;
  135.     register struct RoSAPindication *roi = &rois;
  136.     register struct RoSAPpreject   *rop = &roi -> roi_preject;
  137.     fd_set      rfds;
  138.     fd_set      wfds;
  139.     int    n;
  140.     int fd;
  141.  
  142.     PP_TRACE (("ryresponder (%d, argv, %s, %s...)",
  143.            argc, host, myservice));
  144.     FD_ZERO (&perf_rfds);
  145.     FD_ZERO (&rfds);
  146.     FD_ZERO (&perf_wfds);
  147.     FD_ZERO (&wfds);
  148.  
  149.     if ((myname = rindex (argv[0], '/')) != NULLCP)
  150.         myname++;
  151.     if (myname == NULL || *myname == NULL)
  152.         myname = argv[0];
  153.  
  154.     isodetailor (myname, 0);
  155.     ll_hdinit (pp_log_norm, myname);
  156.  
  157.     if (isatty (fileno (stderr)))
  158.         pp_log_norm -> ll_stat |= LLOGTTY;
  159.     else {
  160.         if (nobackground == 0)
  161.             background ();
  162.             
  163.     }
  164.  
  165.     PP_TRACE (("starting"));
  166.     init_chans ();
  167.  
  168.     for (ds = dispatches; ds -> ds_name; ds++)
  169.         if (RyDispatch (NOTOK, ops, ds -> ds_operation,
  170.                 ds -> ds_vector, roi) == NOTOK)
  171.             ros_adios (rop, ds -> ds_name);
  172.  
  173.     startfnx = start;
  174.     stopfnx = stop;
  175.  
  176.     for (n = 1;; n++) {
  177.         if ((aei = _str2aei (host,myservice, QMGR_CTX_OID, 0,
  178.                      dap_user, dap_passwd)) == NULLAEI)
  179.             adios (NULLCP, "%s %s (%s): unknown service",
  180.                    host, QMGR_CTX_OID, myservice);
  181.  
  182.         if (iserver_init_aux (0, argv, aei, ros_init, TMagic, 1, td) == NOTOK) {
  183.             if (n > 15) {
  184.                 if (td -> td_cc > 0)
  185.                     adios (NULLCP, 
  186.                            "iserver_init: [%s] %*.*s",
  187.                            TErrString (td -> td_reason),
  188.                            td -> td_cc, td -> td_cc,
  189.                            td -> td_data);
  190.                 else
  191.                     adios (NULLCP, "iserver_init: [%s]",
  192.                            TErrString (td -> td_reason));
  193.             }
  194.             if (td -> td_cc > 0)
  195.                 PP_LOG (LLOG_EXCEPTIONS, 
  196.                     ("iserver_init: [%s] %*.*s",
  197.                     TErrString (td -> td_reason),
  198.                     td -> td_cc, td -> td_cc,
  199.                     td -> td_data));
  200.             else
  201.                 PP_LOG (LLOG_EXCEPTIONS,
  202.                     ("iserver_init: [%s]",
  203.                      TErrString (td -> td_reason)));
  204.             sleep ((unsigned) 5 * n);
  205.             continue;
  206.         }
  207.         break;
  208.     }
  209. #ifdef MALLCHK
  210.     _mal_trace_restart ();
  211. #endif
  212.     start_specials ();
  213.  
  214.     PP_TRACE(("Listening"));
  215.  
  216.     for (;;) {
  217.         schedule ();
  218.         rfds = perf_rfds;
  219.         wfds = perf_wfds;
  220.         PP_TRACE (("Main loop..."));
  221.         switch (iserver_wait (ros_init, ros_work, ros_lose, perf_nfds,
  222.                       &rfds, &wfds, NULLFD, delaytime, td)) {
  223.             case DONE:
  224.             return 0;
  225.  
  226.             case NOTOK:
  227.             if (td -> td_cc > 0)
  228.                 adios (NULLCP, "iserver_wait: [%s] %*.*s",
  229.                        TErrString (td -> td_reason),
  230.                        td -> td_cc, td -> td_cc,
  231.                        td -> td_data);
  232.             else
  233.                 adios (NULLCP, "iserver_wait: [%s]",
  234.                        TErrString (td -> td_reason));
  235.             break;
  236.             case OK:
  237.             (void) time (¤t_time);
  238.  
  239.             for (fd = 0; fd < perf_nfds; fd++)
  240.                 if (FD_ISSET (fd, &rfds) ||
  241.                     FD_ISSET (fd, &wfds))
  242.                     chan_manage (fd);
  243.             break;
  244.             default:
  245.             adios (NULLCP, "Illegal return from iserver_wait");
  246.         }
  247.     }
  248. }
  249.  
  250. /*   */
  251.  
  252. static int  ros_init (vecp, vec)
  253. int     vecp;
  254. char  **vec;
  255. {
  256.     int     reply,
  257.         result,
  258.         sd;
  259.     PE    pep[1];
  260.     int    npe = 0;
  261.     struct AcSAPstart   acss;
  262.     register struct AcSAPstart *acs = &acss;
  263.     struct AcSAPindication  acis;
  264.     register struct AcSAPindication *aci = &acis;
  265.     register struct AcSAPabort   *aca = &aci -> aci_abort;
  266.     register struct PSAPstart *ps = &acs -> acs_start;
  267.     struct RoSAPindication  rois;
  268.     register struct RoSAPindication *roi = &rois;
  269.     register struct RoSAPpreject   *rop = &roi -> roi_preject;
  270.     struct TSAPdisconnect   tds;
  271.     struct TSAPdisconnect  *td = &tds;
  272.  
  273.     PP_TRACE (("ros_init (%d, vec)", vecp));
  274.     
  275.     if (AcInit (vecp, vec, acs, aci) == NOTOK) {
  276.         acs_advise (aca, "initialization fails");
  277.         return NOTOK;
  278.     }
  279.     PP_NOTICE (("A-ASSOCIATE.INDICATION/%d", acs -> acs_sd));
  280.     sd = acs -> acs_sd;
  281.     
  282.     for (vec++; *vec; vec++)
  283.         if (**vec)
  284.             PP_LOG (LLOG_EXCEPTIONS,
  285.                 ("unknown argument \"%s\"", *vec));
  286.     
  287.     pep[0] = NULLPE;
  288.     reply = startfnx ? (*startfnx) (sd, acs, pep, &npe) : ACS_ACCEPT;
  289.     
  290.     result = AcAssocResponse (sd, reply, 
  291.                   reply != ACS_ACCEPT ?
  292.                   ACS_USER_NOREASON : ACS_USER_NULL, 
  293.                   NULLOID, NULLAEI, NULLPA, NULLPC,
  294.                   ps -> ps_defctxresult,
  295.                   ps -> ps_prequirements,
  296.                   ps -> ps_srequirements, SERIAL_NONE,
  297.                   ps -> ps_settings, &ps -> ps_connect,
  298.                   pep, npe, aci);
  299.     
  300.     if (pep[0])
  301.         pe_free (pep[0]);
  302.     ACSFREE (acs);
  303.     
  304.     if (result == NOTOK) {
  305.         acs_advise (aca, "A-ASSOCIATE.RESPONSE");
  306.         return NOTOK;
  307.     }
  308.     if (reply != ACS_ACCEPT)
  309.         return NOTOK;
  310.     
  311.     if (RoSetService (sd, RoPService, roi) == NOTOK)
  312.         ros_adios (rop, "set RO/PS fails");
  313.     
  314.     if (TSetQueuesOK (sd, 1, td) == NOTOK) {
  315.         if (td -> td_cc > 0)
  316.             PP_LOG (LLOG_EXCEPTIONS,
  317.                 ("iserver_init: [%s] %*.*s",
  318.                  TErrString (td -> td_reason),
  319.                  td -> td_cc, td -> td_cc,
  320.                  td -> td_data));
  321.         else
  322.             PP_LOG (LLOG_EXCEPTIONS,
  323.                 ("iserver_init: [%s]",
  324.                  TErrString (td -> td_reason)));
  325.         
  326.     }
  327.     return sd;
  328. }
  329.  
  330. /*   */
  331.  
  332. static int  ros_work (fd)
  333. int     fd;
  334. {
  335.     int     result;
  336.     caddr_t out;
  337.     struct AcSAPindication  acis;
  338.     struct RoSAPindication  rois;
  339.     register struct RoSAPindication *roi = &rois;
  340.     register struct RoSAPpreject   *rop = &roi -> roi_preject;
  341.     extern time_t time ();
  342.     
  343.     PP_TRACE (("ros_work (%d)", fd));
  344.     
  345.     (void) time (¤t_time);
  346.     switch (setjmp (toplevel)) {
  347.         case OK: 
  348.         break;
  349.         
  350.         default: 
  351.         if (stopfnx)
  352.             (void) (*stopfnx) (fd, (struct AcSAPfinish *) 0);
  353.         case DONE:
  354.         (void) AcUAbortRequest (fd, NULLPEP, 0, &acis);
  355.         (void) RyLose (fd, roi);
  356.         return NOTOK;
  357.     }
  358.     
  359.     switch (result = RyWait (fd, NULLIP, &out, OK, roi)) {
  360.         case NOTOK: 
  361.         if (rop -> rop_reason == ROS_TIMER)
  362.             break;
  363.         case OK: 
  364.         case DONE: 
  365.         ros_indication (fd, roi);
  366.         break;
  367.         
  368.         default: 
  369.         adios (NULLCP, "unknown return from RoWaitRequest=%d", result);
  370.     }
  371.     
  372.     return OK;
  373. }
  374.  
  375. /*   */
  376.  
  377. static void ros_indication (sd, roi)
  378. int     sd;
  379. register struct RoSAPindication *roi;
  380. {
  381.     int     reply,
  382.     result;
  383.     
  384.     PP_TRACE (("ros_indication (%d)", sd));
  385.     
  386.     switch (roi -> roi_type) {
  387.         case ROI_INVOKE: 
  388.         case ROI_RESULT: 
  389.         case ROI_ERROR: 
  390.         adios (NULLCP, "unexpected indication type=%d",
  391.                roi -> roi_type);
  392.         break;
  393.         
  394.         case ROI_UREJECT: 
  395.     {
  396.         register struct RoSAPureject   *rou =
  397.             &roi -> roi_ureject;
  398.         
  399.         if (rou -> rou_noid)
  400.             PP_LOG (LLOG_EXCEPTIONS,
  401.                 ("RO-REJECT-U.INDICATION/%d: %s",
  402.                  sd, RoErrString (rou -> rou_reason)));
  403.         else
  404.             PP_LOG (LLOG_EXCEPTIONS,
  405.                 ("RO-REJECT-U.INDICATION/%d: %s (id=%d)",
  406.                  sd, RoErrString (rou -> rou_reason),
  407.                  rou -> rou_id));
  408.     }
  409.         break;
  410.         
  411.         case ROI_PREJECT: 
  412.     {
  413.         char tbuf[BUFSIZ];
  414.         register struct RoSAPpreject   *rop = &roi -> roi_preject;
  415.         
  416.         (void) sprintf (tbuf, "RO-REJECT-P.INDICATION/%d",
  417.                 sd);
  418.         if (ROS_FATAL (rop -> rop_reason))
  419.             ros_adios (rop, tbuf);
  420.         ros_advise (rop, tbuf);
  421.     }
  422.         break;
  423.         
  424.         case ROI_FINISH: 
  425.     {
  426.         register struct AcSAPfinish *acf = &roi -> roi_finish;
  427.         struct AcSAPindication  acis;
  428.         register struct AcSAPabort *aca = &acis.aci_abort;
  429.         
  430.         PP_NOTICE (("A-RELEASE.INDICATION/%d: %d",
  431.               sd, acf -> acf_reason));
  432.         
  433.         reply = stopfnx ? (*stopfnx) (sd, acf) : ACS_ACCEPT;
  434.         
  435.         result = AcRelResponse (sd, reply, ACR_NORMAL,
  436.                     NULLPEP, 0, NOTOK, &acis);
  437.         ACFFREE (acf);
  438.         
  439.         if (result == NOTOK)
  440.             acs_advise (aca, "A-RELEASE.RESPONSE");
  441.         else
  442.             if (reply != ACS_ACCEPT)
  443.                 break;
  444.         longjmp (toplevel, DONE);
  445.     }
  446.         /* NOTREACHED */
  447.         
  448.         default: 
  449.         adios (NULLCP, "unknown indication type=%d", roi -> roi_type);
  450.     }
  451. }
  452.  
  453. /*   */
  454.  
  455. static int  ros_lose (td)
  456. struct TSAPdisconnect *td;
  457. {
  458.     PP_TRACE (("ros_lose ()"));
  459.     
  460.     if (td -> td_cc > 0)
  461.         PP_LOG (LLOG_EXCEPTIONS,
  462.             ("TNetAccept: [%s] %*.*s",
  463.              TErrString(td -> td_reason), td -> td_cc, td -> td_cc,
  464.              td -> td_data));
  465.     else
  466.         PP_LOG (LLOG_EXCEPTIONS,
  467.             ("TNetAccept: [%s]",
  468.              TErrString (td -> td_reason)));
  469.     return OK;
  470. }
  471.  
  472. /*     ERRORS */
  473.  
  474. void    ros_adios (rop, event)
  475. register struct RoSAPpreject *rop;
  476. char   *event;
  477. {
  478.     ros_advise (rop, event);
  479.     
  480.     longjmp (toplevel, NOTOK);
  481. }
  482.  
  483.  
  484. void    ros_advise (rop, event)
  485. register struct RoSAPpreject *rop;
  486. char   *event;
  487. {
  488.     char    buffer[BUFSIZ];
  489.     
  490.     if (rop -> rop_cc > 0)
  491.         (void) sprintf (buffer, "[%s] %*.*s",
  492.                 RoErrString (rop -> rop_reason),
  493.                 rop -> rop_cc, rop -> rop_cc, rop -> rop_data);
  494.     else
  495.         (void) sprintf (buffer, "[%s]",
  496.                 RoErrString (rop -> rop_reason));
  497.     
  498.     PP_LOG (LLOG_EXCEPTIONS, ("%s: %s", event, buffer));
  499. }
  500.  
  501. /*   */
  502.  
  503. void    acs_advise (aca, event)
  504. register struct AcSAPabort *aca;
  505. char   *event;
  506. {
  507.     char    buffer[BUFSIZ];
  508.     
  509.     if (aca -> aca_cc > 0)
  510.         (void) sprintf (buffer, "[%s] %*.*s",
  511.                 AcErrString (aca -> aca_reason),
  512.                 aca -> aca_cc, aca -> aca_cc, aca -> aca_data);
  513.     else
  514.         (void) sprintf (buffer, "[%s]",
  515.                 AcErrString (aca -> aca_reason));
  516.     
  517.     PP_LOG (LLOG_EXCEPTIONS, ("%s: %s (source %d)", event, buffer,
  518.                   aca -> aca_source));
  519. }
  520.  
  521. /*   */
  522.  
  523. #ifndef lint
  524. void    adios (va_alist)
  525. va_dcl
  526. {
  527.     va_list ap;
  528.     
  529.     va_start (ap);
  530.     
  531.     _ll_log (pp_log_norm, LLOG_FATAL, ap);
  532.     
  533.     va_end (ap);
  534.     
  535.     _exit (1);
  536. }
  537. #else
  538. /* VARARGS2 */
  539.  
  540. void    adios (what, fmt)
  541. char   *what,
  542.     *fmt;
  543. {
  544.     adios (what, fmt);
  545. }
  546. #endif
  547.  
  548.  
  549. #ifndef lint
  550. /* VARARGS */
  551. void    advise (va_alist)
  552. va_dcl
  553. {
  554.     int     code;
  555.     va_list ap;
  556.  
  557.     va_start (ap);
  558.  
  559.     code = va_arg (ap, int);
  560.  
  561.     _ll_log (pp_log_norm, code, ap);
  562.  
  563.     va_end (ap);
  564. }
  565. #else
  566. /* VARARGS3 */
  567.  
  568. void    advise (code, what, fmt)
  569. char   *what,
  570.        *fmt;
  571. int     code;
  572. {
  573.     advise (code, what, fmt);
  574. }
  575. #endif
  576.  
  577.  
  578. #ifndef lint
  579. void    ryr_advise (va_alist)
  580. va_dcl
  581. {
  582.     va_list ap;
  583.  
  584.     va_start (ap);
  585.  
  586.     _ll_log (pp_log_norm, LLOG_NOTICE, ap);
  587.  
  588.     va_end (ap);
  589. }
  590. #else
  591. /* VARARGS2 */
  592.  
  593. void    ryr_advise (what, fmt)
  594. char   *what,
  595.        *fmt;
  596. {
  597.     ryr_advise (what, fmt);
  598. }
  599. #endif
  600.